#!/usr/bin/python
# -*- coding: utf-8 -*-

import logging

CIN_FILE = 'data/bpmf.cin'
FILE_ENCODING = 'utf-8'

_mapping = {}

def _Initialize():
    state = 0
    keyname = {}
    for line in open(CIN_FILE, 'r'):
        args = [arg.strip() for arg in line.decode(FILE_ENCODING).split()]
        if state == 0:
            if args[0:2] == ['%keyname', 'begin']:
                state = 1
        elif state == 1:
            # Parse key names
            if args[0:2] == ['%keyname', 'end']:
                state = 2
            else:
                keyname[args[0]] = args[1]
        elif state == 2:
            if args[0:2] == ['%chardef', 'begin']:
                state = 3
        elif state == 3:
            # Parse chardef
            if args[0:2] == ['%chardef', 'end']:
                state = 4
            else:
                keynames = [keyname[key] for key in args[0]]
                _mapping[args[1]] = ''.join(keynames)


def _IsAsciiAlnum(c):
    return ((c >= 'a' and c <= 'z') or
            (c >= 'A' and c <= 'Z') or
            (c >= '0' and c <= '9'))


def _GetWordList(string):
    """Returns the list of words in bpmf of string.
    
    Args:
      string: 陳奕迅 Test Word
    Return:
      ['ㄔㄣˊ', 'ㄧˋ’, 'ㄒㄩㄣˋ', 'Test', 'Word']
    """
    word_list = []
    prev_is_alnum = False
    for c in string:
        if _IsAsciiAlnum(c):
            if prev_is_alnum:
                word_list[-1] += c
            else:
                word_list.append(c)
            prev_is_alnum = True
        else:
            if c in _mapping:
                word_list.append(_mapping[c])
            prev_is_alnum = False
    return word_list


def Query(string):
    return ''.join([w[0] for w in _GetWordList(string)])


def _CmpWord(a, b):
    if _IsAsciiAlnum(a[0]) and not _IsAsciiAlnum(b[0]):
        return 1
    elif _IsAsciiAlnum(b[0]) and not _IsAsciiAlnum(a[0]):
        return -1
    elif a > b:
        return 1
    elif b > a:
        return -1
    else:
        return 0
        
        
def Cmp(a, b):
    """Compare a and b by bpmf. Chinese goes first. Then, Latin"""
    wa = _GetWordList(a)
    wb = _GetWordList(b)
    for i in xrange(len(wa)):
        if i >= len(wb):
            return 1
        else:
            v = _CmpWord(wa[i], wb[i])
            if v != 0:
                return v
    if len(wb) > len(wa):
        return -1
    else:
        return 0


def LenCmp(a, b):
    return len(_GetWordList(a)) - len(_GetWordList(b))

_Initialize()
